﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CCL.SocketMessage;

namespace CCL.TableStructure
{
    /// <summary>
    /// 직렬화 가능한 Database의 ProjectRevision Table을 제공합니다.
    /// </summary>
    public class ProjectRevision : Table, ISerializable
    {
        /// <summary>
        /// 해당 Revision의 고유한 ID값을 가져옵니다.
        /// </summary>
        public int RevisionID { get; private set; }
        
        /// <summary>
        /// 해당 Revision의 Revision Number를 가져옵니다.
        /// </summary>
        public int Revision { get; private set; }

        /// <summary>
        /// 해당 Revision을 Commit한 User의 정보를 가져옵니다.
        /// </summary>
        public User UserInfo { get; private set; }
        //public int UserID { get; private set; }

        /// <summary>
        /// Commit된 날짜를 가져옵니다.
        /// </summary>
        public char[] RevisionedDate { get; private set; }

        /// <summary>
        /// 로그메시지를 가져옵니다.
        /// </summary>
        public char[] Log { get; private set; }

        /// <summary>
        /// 해당 Table의 총 Size
        /// </summary>
        public new const int TableSize =
                sizeof(int) +                   // RevisionID
                sizeof(int) +                   // Revision
                User.TableSize +                // User
                Constant.Length.Date +          // RevisionedDate
                Constant.Length.Log;            // Log

        /// <summary>
        /// 새로운 ProjectRevision Table 객체를 생성합니다.
        /// </summary>
        /// <param name="revId"></param>
        /// <param name="proj"></param>
        /// <param name="rev"></param>
        /// <param name="user"></param>
        /// <param name="revDate"></param>
        /// <param name="log"></param>
        public ProjectRevision(int revId, int rev, User user, DateTime revDate, string log)
        {
            RevisionID = revId;
            Revision = rev;
            UserInfo = user;
            RevisionedDate = Utility.StringUtility.StringCopy(revDate.ToString(), Constant.Length.Date);
            Log = Utility.StringUtility.StringCopy(log, Constant.Length.Log);
        }

        /// <summary>
        /// 새로운 ProjectRevision Table 객체를 생성합니다.
        /// </summary>
        /// <param name="bytes">직렬화된 byte 배열</param>
        public ProjectRevision(byte[] bytes)
        {
            int startidx = 0;
            byte[] temp;

            RevisionID = BitConverter.ToInt32(bytes, startidx);
            startidx += sizeof(Int32);

            Revision = BitConverter.ToInt32(bytes, startidx);
            startidx += sizeof(Int32);

            temp = new byte[User.TableSize];
            Array.Copy(bytes, startidx, temp, 0, User.TableSize);
            UserInfo = new User(temp);
            startidx += temp.Length;

            RevisionedDate = new char[Constant.Length.Date];
            Encoding.Default.GetChars(bytes, startidx, Constant.Length.Date, RevisionedDate, 0);

            Log = new char[Constant.Length.Log];
            Encoding.Default.GetChars(bytes, startidx, Constant.Length.Password, Log, 0);
            startidx += Constant.Length.Password;
        }

        /// <summary>
        /// 바이트 배열로 직렬화 합니다.
        /// </summary>
        /// <returns>직렬화된 바이트 배열</returns>
        public byte[] GetByte()
        {
            byte[] bytes = new byte[GetSize()];

            byte[] temp;
            int startIdx = 0;

            temp = BitConverter.GetBytes(RevisionID);
            Array.Copy(temp, 0, bytes, startIdx, temp.Length);
            startIdx += temp.Length;

            temp = BitConverter.GetBytes(Revision);
            Array.Copy(temp, 0, bytes, startIdx, temp.Length);
            startIdx += temp.Length;

            temp = UserInfo.GetByte();
            //temp = BitConverter.GetBytes(UserID);
            Array.Copy(temp, 0, bytes, startIdx, temp.Length);
            startIdx += temp.Length;

            temp = Encoding.Default.GetBytes(RevisionedDate);
            Array.Copy(temp, 0, bytes, startIdx, Constant.Length.Date);
            startIdx += Constant.Length.Date;

            temp = Encoding.Default.GetBytes(Log);
            Array.Copy(temp, 0, bytes, startIdx, Constant.Length.Log);

            return bytes;
        }

        /// <summary>
        /// 직렬화 가능한 객체의 바이트 사이즈를 가져옵니다.
        /// </summary>
        /// <returns>직렬화된 바이트 사이즈</returns>
        public uint GetSize()
        {
            return TableSize;
        }
    }
}
